import jsonpath

from utils.LogUtil import logger


class AssertUtil:

    @staticmethod
    def equals(check_value, expect_value):
        """相等"""
        assert str(check_value) == str(expect_value), f'{check_value} == {expect_value}'

    @staticmethod
    def less_than(check_value, expect_value):
        """小于"""
        assert check_value < expect_value, f'{check_value} < {expect_value})'

    @staticmethod
    def less_than_or_equals(check_value, expect_value):
        """小于等于"""
        assert check_value <= expect_value, f'{check_value} <= {expect_value})'

    @staticmethod
    def greater_than(check_value, expect_value):
        """大于"""
        assert check_value > expect_value, f'{check_value} > {expect_value})'

    @staticmethod
    def greater_than_or_equals(check_value, expect_value):
        """大于等于"""
        assert check_value >= expect_value, f'{check_value} >= {expect_value})'

    @staticmethod
    def result_in_response(check_value, expect_value):
        """结果在响应中"""
        assert check_value in expect_value, f'{check_value} in {expect_value})'

    @staticmethod
    def not_equals(check_value, expect_value):
        """不等于"""
        assert check_value != expect_value, f'{check_value} != {expect_value})'

    @staticmethod
    def contains(check_value, expect_value):
        """包含"""
        assert check_value in expect_value, f'{check_value} in {expect_value})'

    @staticmethod
    def startswith(check_value, expect_value):
        """以什么开头"""
        assert str(check_value).startswith(str(expect_value)), f'{str(check_value)} startswith {str(expect_value)})'

    @staticmethod
    def endswith(check_value, expect_value):
        """以什么结尾"""
        assert str(check_value).endswith(str(expect_value)), f'{str(check_value)} endswith {str(expect_value)})'

    @staticmethod
    def length(check_value, expect_value):
        """校验数量"""
        if not isinstance(check_value, list):
            check_value = [expect_value]
        assert len(check_value) == expect_value, f'{str(check_value)} == {str(expect_value)})'

    def extract_by_jsonpath(self, extract_value: dict, extract_expression: str):
        """
        json path 取值     	用于 测试断言，验证接口响应是否符合预期
        :param extract_value: response.json()
        :param extract_expression: eg: '$.code'
        :return: None或 提取的第一个值 或全部
        """
        # 如果 extract_expression 不是字符串，直接返回原始值
        if not isinstance(extract_expression, str):
            return extract_expression

        # 使用 jsonpath 提取数据
        try:
            extracted = jsonpath.jsonpath(extract_value, extract_expression)
        except Exception as e:
            logger.error(f"JSONPath 解析失败: {e}")
            return None

        # 处理提取结果
        # 无匹配时返回False
        if extracted is False or not extracted:
            return []  # 将 None 转换为空列表
        elif not extracted:  # 空列表
            return None
        elif len(extracted) == 1:  # 单元素列表
            return extracted[0]
        else:  # 多元素列表
            return extracted

    def validate_response(self, response, validate_check):

        """
        断言结果校验
        :param response: 接口返回数据
        :param validate_check: yaml文件断言数据
        :return:
        """
        if validate_check:
            for check in validate_check:
                for check_type, check_value in check.items():
                    # 实际结果
                    actual_value = self.extract_by_jsonpath(response, check_value[0])
                    # 预期结果
                    expect_value = check_value[1]
                    if check_type in ["eq", "equals", "equal"]:
                        self.equals(actual_value, expect_value)
                    elif check_type in ["lt", "less_than"]:
                        self.less_than(actual_value, expect_value)
                    elif check_type in ["le", "less_or_equals"]:
                        self.less_than_or_equals(actual_value, expect_value)
                    elif check_type in ["gt", "greater_than"]:
                        self.greater_than(actual_value, expect_value)
                    elif check_type in ["gtoe", "greater_than_or_equals"]:
                        self.greater_than_or_equals(actual_value, expect_value)
                    elif check_type in ["ne", "not_equal"]:
                        self.not_equals(actual_value, expect_value)
                    elif check_type in ["contains","contain","con"]:
                        self.contains(actual_value, expect_value)
                    elif check_type in ["startswith"]:
                        self.startswith(actual_value, expect_value)
                    elif check_type in ["endswith"]:
                        self.endswith(actual_value, expect_value)
                    elif check_type in ["length"]:
                        self.length(actual_value, expect_value)
                    elif check_type in ["rir"]:
                        self.result_in_response(actual_value, expect_value)
                    else:
                        print(f'{check_type}  not valid check type')
        else:
            logger.info("该接口yaml文件没有断言数据")